package ca.ericslandry.server.handler;

import javax.servlet.http.HttpSession;

import net.customware.gwt.dispatch.server.ActionHandler;
import net.customware.gwt.dispatch.server.ExecutionContext;
import net.customware.gwt.dispatch.shared.Action;
import net.customware.gwt.dispatch.shared.ActionException;
import net.customware.gwt.dispatch.shared.Result;

import org.apache.commons.logging.Log;

import ca.ericslandry.shared.InvalidSessionException;
import ca.ericslandry.shared.domain.User;

import com.google.inject.Inject;
import com.google.inject.Provider;

/**
 * Abstract class which take care of checking if the session is still valid
 * before executing the handler
 */
public abstract class BaseSessionHandler<A extends Action<R>, R extends Result> implements ActionHandler<A, R> {
	protected final Provider<HttpSession> sessionProvider;
	protected final Log logger;

	@Inject
	public BaseSessionHandler(Log logger, Provider<HttpSession> sessionProvider) {
		this.sessionProvider = sessionProvider;
		this.logger = logger;
	}

	/**
	 * Execute executeInternal method
	 */
	public R execute(A action, ExecutionContext context) throws ActionException {
		return executeInternal(action, context);
	}

	/**
	 * Not implemented. Should get overridden if needed
	 */
	public void rollback(A action, R result, ExecutionContext context) throws ActionException {
	}

	protected abstract R executeInternal(A action, ExecutionContext context) throws ActionException;

	/**
	 * Return the User stored in session with the given id
	 * 
	 * @param sessionId
	 * @return user
	 * @throws ActionException
	 */
	protected User getUser() throws ActionException {
		User user = (User) sessionProvider.get().getAttribute("user");
		if (user == null) {
			throw new InvalidSessionException("User not found in session with id " + sessionProvider.get().getId());
		} else {
			return user;
		}
	}
}
